home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i095: Sun RPC Source (rpc2), Part07/11
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: cca!SUN.COM!marks (Mark Stein)
- Mod.sources: Volume 6, Issue 95
- Archive-name: rpc2/Part07
-
- [ "Don't blame me, I'm only the messenger." -r$ ]
-
- Sun RPC source (part 7 of 11). This software package contains code
- and documentation for Revision 3.0 of the Sun Remote Procedure Call
- library. In addition, a beta version of the XDR/RPC protocol compiler
- is included. Comments about this latest release may be mailed to
- sun!rpc or rpc@sun.com.
-
- Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- unrestricted use provided that this legend is included on all tape
- media and as a part of the software program in whole or part. Users
- may copy or modify Sun RPC without charge, but are not authorized to
- license or distribute it to anyone else except as part of a product or
- program developed by the user.
-
- - - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # rpc/rpclib/pmap_clnt.c
- # rpc/rpclib/pmap_getmaps.c
- # rpc/rpclib/pmap_getport.c
- # rpc/rpclib/pmap_prot.c
- # rpc/rpclib/pmap_rmt.c
- # rpc/rpclib/rpc_prot.c
- # rpc/rpclib/svc.c
- # This archive created: Mon Jul 14 16:55:27 1986
- export PATH; PATH=/bin:/usr/bin:$PATH
- for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
- do
- if test ! -d $d
- then
- echo "shar: Making directory $d"
- mkdir $d
- chmod 755 $d
- fi
- done
- echo shar: "extracting 'rpc/rpclib/pmap_clnt.c'" '(4441 characters)'
- if test -f 'rpc/rpclib/pmap_clnt.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/pmap_clnt.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_clnt.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pmap_clnt.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * pmap_clnt.c
- X * Client interface to pmap rpc service.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include <netinet/in.h>
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include "pmap_prot.h"
- X#include "pmap_clnt.h"
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <stdio.h>
- X#include <net/if.h>
- X#include <sys/ioctl.h>
- X#include <arpa/inet.h>
- X#define NAMELEN 255
- X
- Xstatic struct timeval timeout = { 5, 0 };
- Xstatic struct timeval tottimeout = { 60, 0 };
- Xstatic struct sockaddr_in myaddress;
- X
- Xvoid clnt_perror();
- X
- X
- X/*
- X * Set a mapping between program,version and port.
- X * Calls the pmap service remotely to do the mapping.
- X */
- Xbool_t
- Xpmap_set(program, version, protocol, port)
- X u_long program;
- X u_long version;
- X u_long protocol;
- X u_short port;
- X{
- X struct sockaddr_in myaddress;
- X int socket = -1;
- X register CLIENT *client;
- X struct pmap parms;
- X bool_t rslt;
- X
- X get_myaddress(&myaddress);
- X client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
- X timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- X if (client == (CLIENT *)NULL)
- X return (FALSE);
- X parms.pm_prog = program;
- X parms.pm_vers = version;
- X parms.pm_prot = protocol;
- X parms.pm_port = port;
- X if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
- X tottimeout) != RPC_SUCCESS) {
- X clnt_perror(client, "Cannot register service");
- X return (FALSE);
- X }
- X CLNT_DESTROY(client);
- X (void)close(socket);
- X return (rslt);
- X}
- X
- X/*
- X * Remove the mapping between program,version and port.
- X * Calls the pmap service remotely to do the un-mapping.
- X */
- Xbool_t
- Xpmap_unset(program, version)
- X u_long program;
- X u_long version;
- X{
- X struct sockaddr_in myaddress;
- X int socket = -1;
- X register CLIENT *client;
- X struct pmap parms;
- X bool_t rslt;
- X
- X get_myaddress(&myaddress);
- X client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
- X timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- X if (client == (CLIENT *)NULL)
- X return (FALSE);
- X parms.pm_prog = program;
- X parms.pm_vers = version;
- X parms.pm_port = parms.pm_prot = 0;
- X CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
- X tottimeout);
- X CLNT_DESTROY(client);
- X (void)close(socket);
- X return (rslt);
- X}
- X
- X/*
- X * don't use gethostbyname, which would invoke yellow pages
- X */
- Xget_myaddress(addr)
- X struct sockaddr_in *addr;
- X{
- X int s;
- X char buf[BUFSIZ];
- X struct ifconf ifc;
- X struct ifreq ifreq, *ifr;
- X int len;
- X
- X if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- X perror("get_myaddress: socket");
- X exit(1);
- X }
- X ifc.ifc_len = sizeof (buf);
- X ifc.ifc_buf = buf;
- X if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
- X perror("get_myaddress: ioctl (get interface configuration)");
- X exit(1);
- X }
- X ifr = ifc.ifc_req;
- X for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
- X ifreq = *ifr;
- X if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
- X perror("get_myaddress: ioctl");
- X exit(1);
- X }
- X if ((ifreq.ifr_flags & IFF_UP) &&
- X ifr->ifr_addr.sa_family == AF_INET) {
- X *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
- X addr->sin_port = htons(PMAPPORT);
- X break;
- X }
- X ifr++;
- X }
- X close(s);
- X}
- SHAR_EOF
- if test 4441 -ne "`wc -c < 'rpc/rpclib/pmap_clnt.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/pmap_clnt.c'" '(should have been 4441 characters)'
- fi
- chmod 444 'rpc/rpclib/pmap_clnt.c'
- fi
- echo shar: "extracting 'rpc/rpclib/pmap_getmaps.c'" '(2732 characters)'
- if test -f 'rpc/rpclib/pmap_getmaps.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/pmap_getmaps.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_getmaps.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pmap_getmaps.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * pmap_getmap.c
- X * Client interface to pmap rpc service.
- X * contains pmap_getmaps, which is only tcp service involved
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include <netinet/in.h>
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include "pmap_prot.h"
- X#include "pmap_clnt.h"
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <netdb.h>
- X#include <stdio.h>
- X#include <errno.h>
- X#include <net/if.h>
- X#include <sys/ioctl.h>
- X#define NAMELEN 255
- X#define MAX_BROADCAST_SIZE 1400
- X
- Xextern int errno;
- Xstatic struct sockaddr_in myaddress;
- X
- X/*
- X * Get a copy of the current port maps.
- X * Calls the pmap service remotely to do get the maps.
- X */
- Xstruct pmaplist *
- Xpmap_getmaps(address)
- X struct sockaddr_in *address;
- X{
- X struct pmaplist *head = (struct pmaplist *)NULL;
- X int socket = -1;
- X struct timeval minutetimeout;
- X register CLIENT *client;
- X
- X minutetimeout.tv_sec = 60;
- X minutetimeout.tv_usec = 0;
- X address->sin_port = htons(PMAPPORT);
- X client = clnttcp_create(address, PMAPPROG,
- X PMAPVERS, &socket, 50, 500);
- X if (client != (CLIENT *)NULL) {
- X if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
- X &head, minutetimeout) != RPC_SUCCESS) {
- X clnt_perror(client, "pmap_getmaps rpc problem");
- X }
- X CLNT_DESTROY(client);
- X }
- X (void)close(socket);
- X address->sin_port = 0;
- X return (head);
- X}
- SHAR_EOF
- if test 2732 -ne "`wc -c < 'rpc/rpclib/pmap_getmaps.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/pmap_getmaps.c'" '(should have been 2732 characters)'
- fi
- chmod 444 'rpc/rpclib/pmap_getmaps.c'
- fi
- echo shar: "extracting 'rpc/rpclib/pmap_getport.c'" '(2946 characters)'
- if test -f 'rpc/rpclib/pmap_getport.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/pmap_getport.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_getport.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pmap_getport.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * pmap_getport.c
- X * Client interface to pmap rpc service.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include <netinet/in.h>
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include "pmap_prot.h"
- X#include "pmap_clnt.h"
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <stdio.h>
- X#include <net/if.h>
- X#include <sys/ioctl.h>
- X#include <arpa/inet.h>
- X#define NAMELEN 255
- X
- Xstatic struct timeval timeout = { 5, 0 };
- Xstatic struct timeval tottimeout = { 60, 0 };
- X
- X/*
- X * Find the mapped port for program,version.
- X * Calls the pmap service remotely to do the lookup.
- X * Returns 0 if no map exists.
- X */
- Xu_short
- Xpmap_getport(address, program, version, protocol)
- X struct sockaddr_in *address;
- X u_long program;
- X u_long version;
- X u_long protocol;
- X{
- X u_short port = 0;
- X int socket = -1;
- X register CLIENT *client;
- X struct pmap parms;
- X
- X address->sin_port = htons(PMAPPORT);
- X client = clntudp_bufcreate(address, PMAPPROG,
- X PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- X if (client != (CLIENT *)NULL) {
- X parms.pm_prog = program;
- X parms.pm_vers = version;
- X parms.pm_prot = protocol;
- X parms.pm_port = 0; /* not needed or used */
- X if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
- X xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
- X rpc_createerr.cf_stat = RPC_PMAPFAILURE;
- X clnt_geterr(client, &rpc_createerr.cf_error);
- X } else if (port == 0) {
- X rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
- X }
- X CLNT_DESTROY(client);
- X }
- X (void)close(socket);
- X address->sin_port = 0;
- X return (port);
- X}
- SHAR_EOF
- if test 2946 -ne "`wc -c < 'rpc/rpclib/pmap_getport.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/pmap_getport.c'" '(should have been 2946 characters)'
- fi
- chmod 444 'rpc/rpclib/pmap_getport.c'
- fi
- echo shar: "extracting 'rpc/rpclib/pmap_prot.c'" '(4003 characters)'
- if test -f 'rpc/rpclib/pmap_prot.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/pmap_prot.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_prot.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pmap_prot.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * pmap_prot.c
- X * Protocol for the local binder service, or pmap.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include "xdr.h"
- X#include "pmap_prot.h"
- X
- X#define NULL ((struct pmaplist *)0)
- X
- Xbool_t
- Xxdr_pmap(xdrs, regs)
- X XDR *xdrs;
- X struct pmap *regs;
- X{
- X
- X if (xdr_u_long(xdrs, ®s->pm_prog) &&
- X xdr_u_long(xdrs, ®s->pm_vers) &&
- X xdr_u_long(xdrs, ®s->pm_prot))
- X return (xdr_u_long(xdrs, ®s->pm_port));
- X return (FALSE);
- X}
- X
- X/*
- X * What is going on with linked lists? (!)
- X * First recall the link list declaration from pmap_prot.h:
- X *
- X * struct pmaplist {
- X * struct pmap pml_map;
- X * struct pmaplist *pml_map;
- X * };
- X *
- X * Compare that declaration with a corresponding xdr declaration that
- X * is (a) pointer-less, and (b) recursive:
- X *
- X * typedef union switch (bool_t) {
- X *
- X * case TRUE: struct {
- X * struct pmap;
- X * pmaplist_t foo;
- X * };
- X *
- X * case FALSE: struct {};
- X * } pmaplist_t;
- X *
- X * Notice that the xdr declaration has no nxt pointer while
- X * the C declaration has no bool_t variable. The bool_t can be
- X * interpreted as ``more data follows me''; if FALSE then nothing
- X * follows this bool_t; if TRUE then the bool_t is followed by
- X * an actual struct pmap, and then (recursively) by the
- X * xdr union, pamplist_t.
- X *
- X * This could be implemented via the xdr_union primitive, though this
- X * would cause a one recursive call per element in the list. Rather than do
- X * that we can ``unwind'' the recursion
- X * into a while loop and do the union arms in-place.
- X *
- X * The head of the list is what the C programmer wishes to past around
- X * the net, yet is the data that the pointer points to which is interesting;
- X * this sounds like a job for xdr_reference!
- X */
- Xbool_t
- Xxdr_pmaplist(xdrs, rp)
- X register XDR *xdrs;
- X register struct pmaplist **rp;
- X{
- X /*
- X * more_elements is pre-computed in case the direction is
- X * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
- X * xdr_bool when the direction is XDR_DECODE.
- X */
- X bool_t more_elements;
- X register int freeing = (xdrs->x_op == XDR_FREE);
- X register struct pmaplist **next;
- X
- X while (TRUE) {
- X more_elements = (bool_t)(*rp != NULL);
- X if (! xdr_bool(xdrs, &more_elements))
- X return (FALSE);
- X if (! more_elements)
- X return (TRUE); /* we are done */
- X /*
- X * the unfortunate side effect of non-recursion is that in
- X * the case of freeing we must remember the next object
- X * before we free the current object ...
- X */
- X if (freeing)
- X next = &((*rp)->pml_next);
- X if (! xdr_reference(xdrs, (caddr_t *)rp,
- X (u_int)sizeof(struct pmaplist), xdr_pmap))
- X return (FALSE);
- X rp = (freeing) ? next : &((*rp)->pml_next);
- X }
- X}
- SHAR_EOF
- if test 4003 -ne "`wc -c < 'rpc/rpclib/pmap_prot.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/pmap_prot.c'" '(should have been 4003 characters)'
- fi
- chmod 444 'rpc/rpclib/pmap_prot.c'
- fi
- echo shar: "extracting 'rpc/rpclib/pmap_rmt.c'" '(10629 characters)'
- if test -f 'rpc/rpclib/pmap_rmt.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/pmap_rmt.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/pmap_rmt.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)pmap_rmt.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * pmap_rmt.c
- X * Client interface to pmap rpc service.
- X * remote call and broadcast service
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include <netinet/in.h>
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include "pmap_prot.h"
- X#include "pmap_clnt.h"
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <stdio.h>
- X#include <errno.h>
- X#include <net/if.h>
- X#include <sys/ioctl.h>
- X#include <arpa/inet.h>
- X#define MAX_BROADCAST_SIZE 1400
- X
- Xextern int errno;
- Xstatic struct timeval timeout = { 3, 0 };
- X
- X/*
- X * Structures and XDR routines for parameters to and replys from
- X * the pmapper remote-call-service.
- X */
- X
- Xstruct rmtcallargs {
- X u_long prog, vers, proc, arglen;
- X caddr_t args_ptr;
- X xdrproc_t xdr_args;
- X};
- Xstatic bool_t xdr_rmtcall_args();
- X
- Xstruct rmtcallres {
- X u_long *port_ptr;
- X u_long resultslen;
- X caddr_t results_ptr;
- X xdrproc_t xdr_results;
- X};
- Xstatic bool_t xdr_rmtcallres();
- X
- X/*
- X * pmapper remote-call-service interface.
- X * This routine is used to call the pmapper remote call service
- X * which will look up a service program in the port maps, and then
- X * remotely call that routine with the given parameters. This allows
- X * programs to do a lookup and call in one step.
- X*/
- Xenum clnt_stat
- Xpmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
- X struct sockaddr_in *addr;
- X u_long prog, vers, proc;
- X xdrproc_t xdrargs, xdrres;
- X caddr_t argsp, resp;
- X struct timeval tout;
- X u_long *port_ptr;
- X{
- X int socket = -1;
- X register CLIENT *client;
- X struct rmtcallargs a;
- X struct rmtcallres r;
- X enum clnt_stat stat;
- X
- X addr->sin_port = htons(PMAPPORT);
- X client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
- X if (client != (CLIENT *)NULL) {
- X a.prog = prog;
- X a.vers = vers;
- X a.proc = proc;
- X a.args_ptr = argsp;
- X a.xdr_args = xdrargs;
- X r.port_ptr = port_ptr;
- X r.results_ptr = resp;
- X r.xdr_results = xdrres;
- X stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
- X xdr_rmtcallres, &r, tout);
- X CLNT_DESTROY(client);
- X } else {
- X stat = RPC_FAILED;
- X }
- X (void)close(socket);
- X addr->sin_port = 0;
- X return (stat);
- X}
- X
- X/*
- X * XDR remote call arguments
- X * written for XDR_ENCODE direction only
- X */
- Xstatic bool_t
- Xxdr_rmtcall_args(xdrs, cap)
- X register XDR *xdrs;
- X register struct rmtcallargs *cap;
- X{
- X u_int lenposition, argposition, position;
- X
- X if (xdr_u_long(xdrs, &(cap->prog)) &&
- X xdr_u_long(xdrs, &(cap->vers)) &&
- X xdr_u_long(xdrs, &(cap->proc))) {
- X lenposition = XDR_GETPOS(xdrs);
- X if (! xdr_u_long(xdrs, &(cap->arglen)))
- X return (FALSE);
- X argposition = XDR_GETPOS(xdrs);
- X if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
- X return (FALSE);
- X position = XDR_GETPOS(xdrs);
- X cap->arglen = (u_long)position - (u_long)argposition;
- X XDR_SETPOS(xdrs, lenposition);
- X if (! xdr_u_long(xdrs, &(cap->arglen)))
- X return (FALSE);
- X XDR_SETPOS(xdrs, position);
- X return (TRUE);
- X }
- X return (FALSE);
- X}
- X
- X/*
- X * XDR remote call results
- X * written for XDR_DECODE direction only
- X */
- Xstatic bool_t
- Xxdr_rmtcallres(xdrs, crp)
- X register XDR *xdrs;
- X register struct rmtcallres *crp;
- X{
- X
- X if (xdr_reference(xdrs, &crp->port_ptr, sizeof (u_long), xdr_u_long) &&
- X xdr_u_long(xdrs, &crp->resultslen))
- X return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
- X return (FALSE);
- X}
- X
- X/*
- X * The following is kludged-up support for simple rpc broadcasts.
- X * Someday a large, complicated system will replace these trivial
- X * routines which only support udp/ip .
- X */
- X
- Xstatic int
- Xgetbroadcastnets(addrs, sock, buf)
- X struct in_addr *addrs;
- X int sock; /* any valid socket will do */
- X char *buf; /* why allocxate more when we can use existing... */
- X{
- X struct ifconf ifc;
- X struct ifreq ifreq, *ifr;
- X struct sockaddr_in *sin;
- X int n, i;
- X
- X ifc.ifc_len = MAX_BROADCAST_SIZE;
- X ifc.ifc_buf = buf;
- X if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
- X perror("broadcast: ioctl (get interface configuration)");
- X return (0);
- X }
- X ifr = ifc.ifc_req;
- X for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
- X ifreq = *ifr;
- X if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
- X perror("broadcast: ioctl (get interface flags)");
- X continue;
- X }
- X if ((ifreq.ifr_flags & IFF_BROADCAST) &&
- X (ifreq.ifr_flags & IFF_UP) &&
- X ifr->ifr_addr.sa_family == AF_INET) {
- X sin = (struct sockaddr_in *)&ifr->ifr_addr;
- X addrs[i++] = inet_makeaddr(inet_netof
- X (sin->sin_addr.s_addr), INADDR_ANY);
- X }
- X }
- X return (i);
- X}
- X
- Xtypedef bool_t (*resultproc_t)();
- X
- Xenum clnt_stat
- Xclnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
- X u_long prog; /* program number */
- X u_long vers; /* version number */
- X u_long proc; /* procedure number */
- X xdrproc_t xargs; /* xdr routine for args */
- X caddr_t argsp; /* pointer to args */
- X xdrproc_t xresults; /* xdr routine for results */
- X caddr_t resultsp; /* pointer to results */
- X resultproc_t eachresult; /* call with each result obtained */
- X{
- X enum clnt_stat stat;
- X AUTH *unix_auth = authunix_create_default();
- X XDR xdr_stream;
- X register XDR *xdrs = &xdr_stream;
- X int outlen, inlen, fromlen, readfds, nets;
- X register int sock, mask, i;
- X bool_t done = FALSE;
- X register u_long xid;
- X u_long port;
- X struct in_addr addrs[20];
- X struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
- X struct rmtcallargs a;
- X struct rmtcallres r;
- X struct rpc_msg msg;
- X struct timeval t;
- X char outbuf[MAX_BROADCAST_SIZE], inbuf[MAX_BROADCAST_SIZE];
- X
- X /*
- X * initialization: create a socket, a broadcast address, and
- X * preserialize the arguments into a send buffer.
- X */
- X if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- X perror("Cannot create socket for broadcast rpc");
- X stat = RPC_CANTSEND;
- X goto done_broad;
- X }
- X mask = (1 << sock);
- X nets = getbroadcastnets(addrs, sock, inbuf);
- X bzero(&baddr, sizeof (baddr));
- X baddr.sin_family = AF_INET;
- X baddr.sin_port = htons(PMAPPORT);
- X baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
- X (void)gettimeofday(&t, (struct timezone *)0);
- X msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
- X t.tv_usec = 0;
- X msg.rm_direction = CALL;
- X msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
- X msg.rm_call.cb_prog = PMAPPROG;
- X msg.rm_call.cb_vers = PMAPVERS;
- X msg.rm_call.cb_proc = PMAPPROC_CALLIT;
- X msg.rm_call.cb_cred = unix_auth->ah_cred;
- X msg.rm_call.cb_verf = unix_auth->ah_verf;
- X a.prog = prog;
- X a.vers = vers;
- X a.proc = proc;
- X a.xdr_args = xargs;
- X a.args_ptr = argsp;
- X r.port_ptr = &port;
- X r.xdr_results = xresults;
- X r.results_ptr = resultsp;
- X xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
- X if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
- X stat = RPC_CANTENCODEARGS;
- X goto done_broad;
- X }
- X outlen = (int)xdr_getpos(xdrs);
- X xdr_destroy(xdrs);
- X /*
- X * Basic loop: broadcast a packet and wait a while for response(s).
- X * The response timeout grows larger per iteration.
- X */
- X for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
- X for (i = 0; i < nets; i++) {
- X baddr.sin_addr = addrs[i];
- X if (sendto(sock, outbuf, outlen, 0,
- X (struct socketaddr *)&baddr,
- X sizeof (struct sockaddr)) != outlen) {
- X perror("Cannot send broadcast packet");
- X stat = RPC_CANTSEND;
- X goto done_broad;
- X }
- X }
- X recv_again:
- X msg.acpted_rply.ar_verf = _null_auth;
- X msg.acpted_rply.ar_results.where = (caddr_t)&r;
- X msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
- X readfds = mask;
- X switch (select(32, &readfds, (int *)NULL, (int *)NULL, &t)) {
- X
- X case 0: /* timed out */
- X stat = RPC_TIMEDOUT;
- X continue;
- X
- X case -1: /* some kind of error */
- X if (errno == EINTR)
- X goto recv_again;
- X perror("Broadcast select problem");
- X stat = RPC_CANTRECV;
- X goto done_broad;
- X
- X } /* end of select results switch */
- X if ((readfds & mask) == 0)
- X goto recv_again;
- X try_again:
- X fromlen = sizeof(struct sockaddr);
- X inlen = recvfrom(sock, inbuf, MAX_BROADCAST_SIZE, 0,
- X (struct sockaddr *)&raddr, &fromlen);
- X if (inlen < 0) {
- X if (errno == EINTR)
- X goto try_again;
- X perror("Cannot receive reply to broadcast");
- X stat = RPC_CANTRECV;
- X goto done_broad;
- X }
- X if (inlen < sizeof(u_long))
- X goto recv_again;
- X /*
- X * see if reply transaction id matches sent id.
- X * If so, decode the results.
- X */
- X xdrmem_create(xdrs, inbuf, inlen, XDR_DECODE);
- X if (xdr_replymsg(xdrs, &msg)) {
- X if ((msg.rm_xid == xid) &&
- X (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
- X (msg.acpted_rply.ar_stat == SUCCESS)) {
- X raddr.sin_port = htons((u_short)port);
- X done = (*eachresult)(resultsp, &raddr);
- X }
- X /* otherwise, we just ignore the errors ... */
- X } else {
- X#ifdef notdef
- X /* some kind of deserialization problem ... */
- X if (msg.rm_xid == xid)
- X fprintf(stderr, "Broadcast deserialization problem");
- X /* otherwise, just random garbage */
- X#endif
- X }
- X xdrs->x_op = XDR_FREE;
- X msg.acpted_rply.ar_results.proc = xdr_void;
- X (void)xdr_replymsg(xdrs, &msg);
- X (void)(*xresults)(xdrs, resultsp);
- X xdr_destroy(xdrs);
- X if (done) {
- X stat = RPC_SUCCESS;
- X goto done_broad;
- X } else {
- X goto recv_again;
- X }
- X }
- Xdone_broad:
- X (void)close(sock);
- X AUTH_DESTROY(unix_auth);
- X return (stat);
- X}
- SHAR_EOF
- if test 10629 -ne "`wc -c < 'rpc/rpclib/pmap_rmt.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/pmap_rmt.c'" '(should have been 10629 characters)'
- fi
- chmod 444 'rpc/rpclib/pmap_rmt.c'
- fi
- echo shar: "extracting 'rpc/rpclib/rpc_prot.c'" '(14335 characters)'
- if test -f 'rpc/rpclib/rpc_prot.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/rpc_prot.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/rpc_prot.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)rpc_prot.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * rpc_prot.c
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X *
- X * This set of routines implements the rpc message definition,
- X * its serializer and some common rpc utility routines.
- X * The routines are meant for various implementations of rpc -
- X * they are NOT for the rpc client or rpc service implementations!
- X * Because authentication stuff is easy and is part of rpc, the opaque
- X * routines are also in this program.
- X */
- X
- X#include <sys/param.h>
- X#include "types.h"
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include <netinet/in.h>
- X
- X/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
- X
- Xstruct opaque_auth _null_auth;
- X
- X/*
- X * XDR an opaque authentication struct
- X * (see auth.h)
- X */
- Xbool_t
- Xxdr_opaque_auth(xdrs, ap)
- X register XDR *xdrs;
- X register struct opaque_auth *ap;
- X{
- X
- X if (xdr_enum(xdrs, &(ap->oa_flavor)))
- X return (xdr_bytes(xdrs, &ap->oa_base,
- X &ap->oa_length, MAX_AUTH_BYTES));
- X return (FALSE);
- X}
- X
- X/*
- X * XDR a DES key.
- X */
- Xbool_t
- Xxdr_deskey(xdrs, blkp)
- X register XDR *xdrs;
- X register union des_block *blkp;
- X{
- X
- X if (! xdr_u_long(xdrs, &(blkp->key.high)))
- X return (FALSE);
- X return (xdr_u_long(xdrs, &(blkp->key.low)));
- X}
- X
- X/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
- X
- X/*
- X * XDR the MSG_ACCEPTED part of a reply message union
- X */
- Xbool_t
- Xxdr_accepted_reply(xdrs, ar)
- X register XDR *xdrs;
- X register struct accepted_reply *ar;
- X{
- X
- X /* personalized union, rather than calling xdr_union */
- X if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
- X return (FALSE);
- X if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
- X return (FALSE);
- X switch (ar->ar_stat) {
- X
- X case SUCCESS:
- X return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
- X
- X case PROG_MISMATCH:
- X if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
- X return (FALSE);
- X return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
- X }
- X return (TRUE); /* TRUE => open ended set of problems */
- X}
- X
- X/*
- X * XDR the MSG_DENIED part of a reply message union
- X */
- Xbool_t
- Xxdr_rejected_reply(xdrs, rr)
- X register XDR *xdrs;
- X register struct rejected_reply *rr;
- X{
- X
- X /* personalized union, rather than calling xdr_union */
- X if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
- X return (FALSE);
- X switch (rr->rj_stat) {
- X
- X case RPC_MISMATCH:
- X if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
- X return (FALSE);
- X return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
- X
- X case AUTH_ERROR:
- X return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
- X }
- X return (FALSE);
- X}
- X
- X#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
- X * BYTES_PER_XDR_UNIT)
- X
- Xstatic struct xdr_discrim reply_dscrm[3] = {
- X { (int)MSG_ACCEPTED, xdr_accepted_reply },
- X { (int)MSG_DENIED, xdr_rejected_reply },
- X { __dontcare__, NULL_xdrproc_t } };
- X
- X/*
- X * XDR a reply message
- X */
- Xbool_t
- Xxdr_replymsg(xdrs, rmsg)
- X register XDR *xdrs;
- X register struct rpc_msg *rmsg;
- X{
- X register long *buf;
- X register struct accepted_reply *ar;
- X register struct opaque_auth *oa;
- X
- X if (xdrs->x_op == XDR_ENCODE &&
- X rmsg->rm_reply.rp_stat == MSG_ACCEPTED &&
- X rmsg->rm_direction == REPLY &&
- X (buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT +
- X rmsg->rm_reply.rp_acpt.ar_verf.oa_length)) != NULL) {
- X IXDR_PUT_LONG(buf, rmsg->rm_xid);
- X IXDR_PUT_ENUM(buf, rmsg->rm_direction);
- X IXDR_PUT_ENUM(buf, rmsg->rm_reply.rp_stat);
- X ar = &rmsg->rm_reply.rp_acpt;
- X oa = &ar->ar_verf;
- X IXDR_PUT_ENUM(buf, oa->oa_flavor);
- X IXDR_PUT_LONG(buf, oa->oa_length);
- X if (oa->oa_length) {
- X bcopy(oa->oa_base, buf, oa->oa_length);
- X buf += (oa->oa_length +
- X BYTES_PER_XDR_UNIT - 1) /
- X sizeof (long);
- X }
- X /*
- X * stat and rest of reply, copied from xdr_accepted_reply
- X */
- X IXDR_PUT_ENUM(buf, ar->ar_stat);
- X switch (ar->ar_stat) {
- X
- X case SUCCESS:
- X return ((*(ar->ar_results.proc))
- X (xdrs, ar->ar_results.where));
- X
- X case PROG_MISMATCH:
- X if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
- X return (FALSE);
- X return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
- X }
- X return (TRUE);
- X }
- X if (xdrs->x_op == XDR_DECODE &&
- X (buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT)) != NULL) {
- X rmsg->rm_xid = IXDR_GET_LONG(buf);
- X rmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
- X if (rmsg->rm_direction != REPLY) {
- X return (FALSE);
- X }
- X rmsg->rm_reply.rp_stat = IXDR_GET_ENUM(buf, enum reply_stat);
- X if (rmsg->rm_reply.rp_stat != MSG_ACCEPTED) {
- X if (rmsg->rm_reply.rp_stat == MSG_DENIED) {
- X return (xdr_rejected_reply(xdrs,
- X &rmsg->rm_reply.rp_rjct));
- X }
- X return (FALSE);
- X }
- X ar = &rmsg->rm_reply.rp_acpt;
- X oa = &ar->ar_verf;
- X buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- X if (buf != NULL) {
- X oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
- X oa->oa_length = IXDR_GET_LONG(buf);
- X } else {
- X if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
- X xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
- X return (FALSE);
- X }
- X }
- X if (oa->oa_length) {
- X if (oa->oa_length > MAX_AUTH_BYTES) {
- X return (FALSE);
- X }
- X if (oa->oa_base == NULL) {
- X oa->oa_base = (caddr_t)
- X mem_alloc(oa->oa_length);
- X }
- X buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
- X if (buf == NULL) {
- X if (xdr_opaque(xdrs, oa->oa_base,
- X oa->oa_length) == FALSE) {
- X return (FALSE);
- X }
- X } else {
- X bcopy(buf, oa->oa_base, oa->oa_length);
- X /* no real need....
- X buf += RNDUP(oa->oa_length) / sizeof (long);
- X */
- X }
- X }
- X /*
- X * stat and rest of reply, copied from
- X * xdr_accepted_reply
- X */
- X xdr_enum(xdrs, &ar->ar_stat);
- X switch (ar->ar_stat) {
- X
- X case SUCCESS:
- X return ((*(ar->ar_results.proc))
- X (xdrs, ar->ar_results.where));
- X
- X case PROG_MISMATCH:
- X if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
- X return (FALSE);
- X return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
- X }
- X return (TRUE);
- X }
- X if (
- X xdr_u_long(xdrs, &(rmsg->rm_xid)) &&
- X xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
- X (rmsg->rm_direction == REPLY) )
- X return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
- X (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
- X return (FALSE);
- X}
- X
- X/*
- X * XDR a call message
- X */
- Xbool_t
- Xxdr_callmsg(xdrs, cmsg)
- X register XDR *xdrs;
- X register struct rpc_msg *cmsg;
- X{
- X register long *buf;
- X register struct opaque_auth *oa;
- X
- X if (xdrs->x_op == XDR_ENCODE) {
- X if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
- X return (FALSE);
- X }
- X if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
- X return (FALSE);
- X }
- X buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
- X + RNDUP(cmsg->rm_call.cb_cred.oa_length)
- X + 2 * BYTES_PER_XDR_UNIT
- X + RNDUP(cmsg->rm_call.cb_verf.oa_length));
- X if (buf != NULL) {
- X IXDR_PUT_LONG(buf, cmsg->rm_xid);
- X IXDR_PUT_ENUM(buf, cmsg->rm_direction);
- X if (cmsg->rm_direction != CALL) {
- X return (FALSE);
- X }
- X IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
- X if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
- X return (FALSE);
- X }
- X IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
- X IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
- X IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
- X oa = &cmsg->rm_call.cb_cred;
- X IXDR_PUT_ENUM(buf, oa->oa_flavor);
- X IXDR_PUT_LONG(buf, oa->oa_length);
- X if (oa->oa_length) {
- X bcopy(oa->oa_base, buf, oa->oa_length);
- X buf += RNDUP(oa->oa_length) / sizeof (long);
- X }
- X oa = &cmsg->rm_call.cb_verf;
- X IXDR_PUT_ENUM(buf, oa->oa_flavor);
- X IXDR_PUT_LONG(buf, oa->oa_length);
- X if (oa->oa_length) {
- X bcopy(oa->oa_base, buf, oa->oa_length);
- X /* no real need....
- X buf += RNDUP(oa->oa_length) / sizeof (long);
- X */
- X }
- X return (TRUE);
- X }
- X }
- X if (xdrs->x_op == XDR_DECODE) {
- X buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
- X if (buf != NULL) {
- X cmsg->rm_xid = IXDR_GET_LONG(buf);
- X cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
- X if (cmsg->rm_direction != CALL) {
- X return (FALSE);
- X }
- X cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
- X if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
- X return (FALSE);
- X }
- X cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
- X cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
- X cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
- X oa = &cmsg->rm_call.cb_cred;
- X oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
- X oa->oa_length = IXDR_GET_LONG(buf);
- X if (oa->oa_length) {
- X if (oa->oa_length > MAX_AUTH_BYTES) {
- X return (FALSE);
- X }
- X if (oa->oa_base == NULL) {
- X oa->oa_base = (caddr_t)
- X mem_alloc(oa->oa_length);
- X }
- X buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
- X if (buf == NULL) {
- X if (xdr_opaque(xdrs, oa->oa_base,
- X oa->oa_length) == FALSE) {
- X return (FALSE);
- X }
- X } else {
- X bcopy(buf, oa->oa_base, oa->oa_length);
- X /* no real need....
- X buf += RNDUP(oa->oa_length) /
- X sizeof (long);
- X */
- X }
- X }
- X oa = &cmsg->rm_call.cb_verf;
- X buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- X if (buf == NULL) {
- X if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
- X xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
- X return (FALSE);
- X }
- X } else {
- X oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
- X oa->oa_length = IXDR_GET_LONG(buf);
- X }
- X if (oa->oa_length) {
- X if (oa->oa_length > MAX_AUTH_BYTES) {
- X return (FALSE);
- X }
- X if (oa->oa_base == NULL) {
- X oa->oa_base = (caddr_t)
- X mem_alloc(oa->oa_length);
- X }
- X buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
- X if (buf == NULL) {
- X if (xdr_opaque(xdrs, oa->oa_base,
- X oa->oa_length) == FALSE) {
- X return (FALSE);
- X }
- X } else {
- X bcopy(buf, oa->oa_base, oa->oa_length);
- X /* no real need...
- X buf += RNDUP(oa->oa_length) /
- X sizeof (long);
- X */
- X }
- X }
- X return (TRUE);
- X }
- X }
- X if (
- X xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
- X xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
- X (cmsg->rm_direction == CALL) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
- X (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
- X xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
- X return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
- X return (FALSE);
- X}
- X
- X/*
- X * Serializes the "static part" of a call message header.
- X * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
- X * The rm_xid is not really static, but the user can easily munge on the fly.
- X */
- Xbool_t
- Xxdr_callhdr(xdrs, cmsg)
- X register XDR *xdrs;
- X register struct rpc_msg *cmsg;
- X{
- X
- X cmsg->rm_direction = CALL;
- X cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
- X if (
- X (xdrs->x_op == XDR_ENCODE) &&
- X xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
- X xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
- X xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
- X return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
- X return (FALSE);
- X}
- X
- X/* ************************** Client utility routine ************* */
- X
- Xstatic void
- Xaccepted(acpt_stat, error)
- X register enum accept_stat acpt_stat;
- X register struct rpc_err *error;
- X{
- X
- X switch (acpt_stat) {
- X
- X case PROG_UNAVAIL:
- X error->re_status = RPC_PROGUNAVAIL;
- X return;
- X
- X case PROG_MISMATCH:
- X error->re_status = RPC_PROGVERSMISMATCH;
- X return;
- X
- X case PROC_UNAVAIL:
- X error->re_status = RPC_PROCUNAVAIL;
- X return;
- X
- X case GARBAGE_ARGS:
- X error->re_status = RPC_CANTDECODEARGS;
- X return;
- X
- X case SYSTEM_ERR:
- X error->re_status = RPC_SYSTEMERROR;
- X return;
- X
- X case SUCCESS:
- X error->re_status = RPC_SUCCESS;
- X return;
- X }
- X /* something's wrong, but we don't know what ... */
- X error->re_status = RPC_FAILED;
- X error->re_lb.s1 = (long)MSG_ACCEPTED;
- X error->re_lb.s2 = (long)acpt_stat;
- X}
- X
- Xstatic void
- Xrejected(rjct_stat, error)
- X register enum reject_stat rjct_stat;
- X register struct rpc_err *error;
- X{
- X
- X switch (rjct_stat) {
- X
- X case RPC_VERSMISMATCH:
- X error->re_status = RPC_VERSMISMATCH;
- X return;
- X
- X case AUTH_ERROR:
- X error->re_status = RPC_AUTHERROR;
- X return;
- X }
- X /* something's wrong, but we don't know what ... */
- X error->re_status = RPC_FAILED;
- X error->re_lb.s1 = (long)MSG_DENIED;
- X error->re_lb.s2 = (long)rjct_stat;
- X}
- X
- X/*
- X * given a reply message, fills in the error
- X */
- Xvoid
- X_seterr_reply(msg, error)
- X register struct rpc_msg *msg;
- X register struct rpc_err *error;
- X{
- X
- X /* optimized for normal, SUCCESSful case */
- X switch (msg->rm_reply.rp_stat) {
- X
- X case MSG_ACCEPTED:
- X if (msg->acpted_rply.ar_stat == SUCCESS) {
- X error->re_status = RPC_SUCCESS;
- X return;
- X };
- X accepted(msg->acpted_rply.ar_stat, error);
- X break;
- X
- X case MSG_DENIED:
- X rejected(msg->rjcted_rply.rj_stat, error);
- X break;
- X
- X default:
- X error->re_status = RPC_FAILED;
- X error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
- X break;
- X }
- X switch (error->re_status) {
- X
- X case RPC_VERSMISMATCH:
- X error->re_vers.low = msg->rjcted_rply.rj_vers.low;
- X error->re_vers.high = msg->rjcted_rply.rj_vers.high;
- X break;
- X
- X case RPC_AUTHERROR:
- X error->re_why = msg->rjcted_rply.rj_why;
- X break;
- X
- X case RPC_PROGVERSMISMATCH:
- X error->re_vers.low = msg->acpted_rply.ar_vers.low;
- X error->re_vers.high = msg->acpted_rply.ar_vers.high;
- X break;
- X }
- X}
- SHAR_EOF
- if test 14335 -ne "`wc -c < 'rpc/rpclib/rpc_prot.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/rpc_prot.c'" '(should have been 14335 characters)'
- fi
- chmod 444 'rpc/rpclib/rpc_prot.c'
- fi
- echo shar: "extracting 'rpc/rpclib/svc.c'" '(10663 characters)'
- if test -f 'rpc/rpclib/svc.c'
- then
- echo shar: "will not over-write existing file 'rpc/rpclib/svc.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'rpc/rpclib/svc.c'
- X/*
- X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- X * unrestricted use provided that this legend is included on all tape
- X * media and as a part of the software program in whole or part. Users
- X * may copy or modify Sun RPC without charge, but are not authorized
- X * to license or distribute it to anyone else except as part of a product or
- X * program developed by the user.
- X *
- X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- X *
- X * Sun RPC is provided with no support and without any obligation on the
- X * part of Sun Microsystems, Inc. to assist in its use, correction,
- X * modification or enhancement.
- X *
- X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- X * OR ANY PART THEREOF.
- X *
- X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- X * or profits or other special, indirect and consequential damages, even if
- X * Sun has been advised of the possibility of such damages.
- X *
- X * Sun Microsystems, Inc.
- X * 2550 Garcia Avenue
- X * Mountain View, California 94043
- X */
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)svc.c 1.1 86/02/03 Copyr 1984 Sun Micro";
- X#endif
- X
- X/*
- X * svc.c, Server-side remote procedure call interface.
- X *
- X * There are two sets of procedures here. The xprt routines are
- X * for handling transport handles. The svc routines handle the
- X * list of service routines.
- X *
- X * Copyright (C) 1984, Sun Microsystems, Inc.
- X */
- X
- X#include "types.h"
- X#include <sys/errno.h>
- X#include <sys/time.h>
- X#include <netinet/in.h>
- X#include "xdr.h"
- X#include "auth.h"
- X#include "clnt.h"
- X#include "rpc_msg.h"
- X#include "svc.h"
- X#include "svc_auth.h"
- X#include "pmap_clnt.h"
- X
- X#define NOFILE 32
- X
- Xstatic SVCXPRT *xports[NOFILE];
- Xint svc_fds;
- Xextern errno;
- Xchar *malloc();
- X
- X#define NULL_SVC ((struct svc_callout *)0)
- X#define RQCRED_SIZE 400
- X
- X/*
- X * The services list
- X * Each entry represents a set of procedures (an rpc program).
- X * The dispatch routine takes request structs and runs the
- X * apropriate procedure.
- X */
- Xstatic struct svc_callout {
- X struct svc_callout *sc_next;
- X u_long sc_prog;
- X u_long sc_vers;
- X void (*sc_dispatch)();
- X} *svc_head;
- X
- Xstatic struct svc_callout *svc_find();
- X
- X/* *************** SVCXPRT related stuff **************** */
- X
- X/*
- X * Activate a transport handle.
- X */
- Xvoid
- Xxprt_register(xprt)
- X SVCXPRT *xprt;
- X{
- X register int sock = xprt->xp_sock;
- X
- X if (sock < NOFILE) {
- X xports[sock] = xprt;
- X svc_fds |= (1 << sock);
- X }
- X}
- X
- X/*
- X * De-activate a transport handle.
- X */
- Xvoid
- Xxprt_unregister(xprt)
- X SVCXPRT *xprt;
- X{
- X register int sock = xprt->xp_sock;
- X
- X if ((sock < NOFILE) && (xports[sock] == xprt)) {
- X xports[sock] = (SVCXPRT *)0;
- X svc_fds &= ~(1 << sock);
- X }
- X}
- X
- X
- X/* ********************** CALLOUT list related stuff ************* */
- X
- X/*
- X * Add a service program to the callout list.
- X * The dispatch routine will be called when a rpc request for this
- X * program number comes in.
- X */
- Xbool_t
- Xsvc_register(xprt, prog, vers, dispatch, protocol)
- X SVCXPRT *xprt;
- X u_long prog;
- X u_long vers;
- X void (*dispatch)();
- X int protocol;
- X{
- X struct svc_callout *prev;
- X register struct svc_callout *s;
- X
- X if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
- X if (s->sc_dispatch == dispatch)
- X goto pmap_it; /* he is registering another xptr */
- X return (FALSE);
- X }
- X s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
- X if (s == (struct svc_callout *)0) {
- X return (FALSE);
- X }
- X s->sc_prog = prog;
- X s->sc_vers = vers;
- X s->sc_dispatch = dispatch;
- X s->sc_next = svc_head;
- X svc_head = s;
- Xpmap_it:
- X /* now register the information with the local binder service */
- X if (protocol) {
- X return (pmap_set(prog, vers, protocol, xprt->xp_port));
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * Remove a service program from the callout list.
- X */
- Xvoid
- Xsvc_unregister(prog, vers)
- X u_long prog;
- X u_long vers;
- X{
- X struct svc_callout *prev;
- X register struct svc_callout *s;
- X
- X if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
- X return;
- X if (prev == NULL_SVC) {
- X svc_head = s->sc_next;
- X } else {
- X prev->sc_next = s->sc_next;
- X }
- X s->sc_next = NULL_SVC;
- X mem_free((char *) s, (u_int) sizeof(struct svc_callout));
- X /* now unregister the information with the local binder service */
- X (void)pmap_unset(prog, vers);
- X}
- X
- X/*
- X * Search the callout list for a program number, return the callout
- X * struct.
- X */
- Xstatic struct svc_callout *
- Xsvc_find(prog, vers, prev)
- X u_long prog;
- X u_long vers;
- X struct svc_callout **prev;
- X{
- X register struct svc_callout *s, *p;
- X
- X p = NULL_SVC;
- X for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
- X if ((s->sc_prog == prog) && (s->sc_vers == vers))
- X goto done;
- X p = s;
- X }
- Xdone:
- X *prev = p;
- X return (s);
- X}
- X
- X/* ******************* REPLY GENERATION ROUTINES ************ */
- X
- X/*
- X * Send a reply to an rpc request
- X */
- Xbool_t
- Xsvc_sendreply(xprt, xdr_results, xdr_location)
- X register SVCXPRT *xprt;
- X xdrproc_t xdr_results;
- X caddr_t xdr_location;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = SUCCESS;
- X rply.acpted_rply.ar_results.where = xdr_location;
- X rply.acpted_rply.ar_results.proc = xdr_results;
- X return (SVC_REPLY(xprt, &rply));
- X}
- X
- X/*
- X * No procedure error reply
- X */
- Xvoid
- Xsvcerr_noproc(xprt)
- X register SVCXPRT *xprt;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = PROC_UNAVAIL;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/*
- X * Can't decode args error reply
- X */
- Xvoid
- Xsvcerr_decode(xprt)
- X register SVCXPRT *xprt;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = GARBAGE_ARGS;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/*
- X * Some system error
- X */
- Xvoid
- Xsvcerr_systemerr(xprt)
- X register SVCXPRT *xprt;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = SYSTEM_ERR;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/*
- X * Authentication error reply
- X */
- Xvoid
- Xsvcerr_auth(xprt, why)
- X SVCXPRT *xprt;
- X enum auth_stat why;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_DENIED;
- X rply.rjcted_rply.rj_stat = AUTH_ERROR;
- X rply.rjcted_rply.rj_why = why;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/*
- X * Auth too weak error reply
- X */
- Xvoid
- Xsvcerr_weakauth(xprt)
- X SVCXPRT *xprt;
- X{
- X
- X svcerr_auth(xprt, AUTH_TOOWEAK);
- X}
- X
- X/*
- X * Program unavailable error reply
- X */
- Xvoid
- Xsvcerr_noprog(xprt)
- X register SVCXPRT *xprt;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = PROG_UNAVAIL;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/*
- X * Program version mismatch error reply
- X */
- Xvoid
- Xsvcerr_progvers(xprt, low_vers, high_vers)
- X register SVCXPRT *xprt;
- X u_long low_vers;
- X u_long high_vers;
- X{
- X struct rpc_msg rply;
- X
- X rply.rm_direction = REPLY;
- X rply.rm_reply.rp_stat = MSG_ACCEPTED;
- X rply.acpted_rply.ar_verf = xprt->xp_verf;
- X rply.acpted_rply.ar_stat = PROG_MISMATCH;
- X rply.acpted_rply.ar_vers.low = low_vers;
- X rply.acpted_rply.ar_vers.high = high_vers;
- X SVC_REPLY(xprt, &rply);
- X}
- X
- X/* ******************* SERVER INPUT STUFF ******************* */
- X
- X/*
- X * Get server side input from some transport.
- X *
- X * Statement of authentication parameters management:
- X * This function owns and manages all authentication parameters, specifically
- X * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
- X * the "cooked" credentials (rqst->rq_clntcred). However, this function
- X * does not know the structure of the cooked credentials, so it make the
- X * following two assumptions: a) the structure is contiguous (no pointers), and
- X * b) the structure size does not exceed RQCRED_SIZE bytes.
- X * In all events, all three parameters are freed upon exit from this routine.
- X * The storage is trivially management on the call stack in user land, but
- X * is mallocated in kernel land.
- X */
- Xvoid
- Xsvc_getreq(rdfds)
- X int rdfds;
- X{
- X register enum xprt_stat stat;
- X struct rpc_msg msg;
- X int prog_found;
- X u_long low_vers;
- X u_long high_vers;
- X struct svc_req r;
- X register int sock;
- X register int readfds = rdfds & svc_fds;
- X register SVCXPRT *xprt;
- X char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
- X msg.rm_call.cb_cred.oa_base = cred_area;
- X msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
- X r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
- X
- X for (sock = 0; readfds != 0; sock++, readfds >>= 1) {
- X if ((readfds & 1) != 0) {
- X /* sock has input waiting */
- X xprt = xports[sock];
- X /* now receive msgs from xprtprt (support batch calls) */
- X do {
- X if (SVC_RECV(xprt, &msg)) {
- X
- X /* now find the exported program and call it */
- X register struct svc_callout *s;
- X enum auth_stat why;
- X
- X r.rq_xprt = xprt;
- X r.rq_prog = msg.rm_call.cb_prog;
- X r.rq_vers = msg.rm_call.cb_vers;
- X r.rq_proc = msg.rm_call.cb_proc;
- X r.rq_cred = msg.rm_call.cb_cred;
- X /* first authenticate the message */
- X if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
- X svcerr_auth(xprt, why);
- X goto call_done;
- X }
- X /* now match message with a registered service*/
- X prog_found = FALSE;
- X low_vers = 0 - 1;
- X high_vers = 0;
- X for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
- X if (s->sc_prog == r.rq_prog) {
- X if (s->sc_vers == r.rq_vers) {
- X (*s->sc_dispatch)(&r, xprt);
- X goto call_done;
- X } /* found correct version */
- X prog_found = TRUE;
- X if (s->sc_vers < low_vers)
- X low_vers = s->sc_vers;
- X if (s->sc_vers > high_vers)
- X high_vers = s->sc_vers;
- X } /* found correct program */
- X }
- X /*
- X * if we got here, the program or version
- X * is not served ...
- X */
- X if (prog_found)
- X svcerr_progvers(xprt,
- X low_vers, high_vers);
- X else
- X svcerr_noprog(xprt);
- X /* Fall through to ... */
- X }
- X call_done:
- X if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
- X SVC_DESTROY(xprt);
- X break;
- X }
- X } while (stat == XPRT_MOREREQS);
- X }
- X }
- X}
- X
- X
- X/*
- X * This is the rpc server side idle loop
- X * Wait for input, call server program.
- X */
- Xvoid
- Xsvc_run()
- X{
- X int readfds;
- X
- X while (TRUE) {
- X readfds = svc_fds;
- X switch (select(32, &readfds, (int *)0, (int *)0,
- X (struct timeval *)0)) {
- X
- X case -1:
- X if (errno == EINTR)
- X continue;
- X else {
- X perror("svc.c: - Select failed");
- X return;
- X }
- X case 0:
- X continue;
- X default:
- X svc_getreq(readfds);
- X }
- X }
- X}
- SHAR_EOF
- if test 10663 -ne "`wc -c < 'rpc/rpclib/svc.c'`"
- then
- echo shar: "error transmitting 'rpc/rpclib/svc.c'" '(should have been 10663 characters)'
- fi
- chmod 444 'rpc/rpclib/svc.c'
- fi
- exit 0
- # End of shell archive
-
-